package permission

import (
	"context"
	"errors"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"private-domain-overseas-service/admin/business/api/internal/repository/permission"
	"private-domain-overseas-service/admin/business/api/internal/svc"
	"private-domain-overseas-service/admin/business/api/internal/types"
	"private-domain-overseas-service/pkg/common"
	"private-domain-overseas-service/pkg/status/bizadmin"
	"private-domain-overseas-service/pkg/xerr"
	"private-domain-overseas-service/tools/ent"
	"private-domain-overseas-service/tools/ent/adminrole"
	"private-domain-overseas-service/tools/ent/adminrouter"
	"private-domain-overseas-service/tools/ent/predicate"
	"strconv"
)

type AdminRouterEditLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewAdminRouterEditLogic - 后台菜单编辑接口
func NewAdminRouterEditLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminRouterEditLogic {
	return &AdminRouterEditLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminRouterEditLogic) AdminRouterEdit(req *types.AdminRouterEditRequest) error {
	adminRouterDAO := permission.NewAdminRouterDao(l.ctx, l.svcCtx)

	err := common.WithTx(l.ctx, l.svcCtx.Orm, func(tx *ent.Tx) error {
		if req.OperateType == bizadmin.TypeAdd {
			// 如果不是一级路由
			if req.AdminRouterPid != 0 {
				// 查询按钮是否有父级
				conditions := make([]predicate.AdminRouter, 0, 1)
				conditions = append(conditions, adminrouter.IDEQ(int(req.AdminRouterPid)))
				router, fatherErr := adminRouterDAO.AdminRouterFirst(conditions)
				if fatherErr != nil {
					return errors.New(fmt.Sprintf("查父级路由失败: %v", fatherErr.Error()))
				}

				// 如果父亲是按钮，返回
				if router.AdminRouterMenuType == bizadmin.TypeButton {
					return errors.New(fmt.Sprintf("不能给按钮添加路由"))
				}
			}

			// 新增路由
			routerId, err := adminRouterDAO.AdminRouterCreate(req, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("新增路由失败: %v", err.Error()))
			}

			// 更新角色
			return l.handleUpdateRole(req, tx, routerId)
		}

		// 更新
		if req.OperateType == bizadmin.TypeEdit {
			// 把请求体转为内部数据结构
			request := &ent.AdminRouter{
				ID:                    int(req.Id),
				AdminRouterMenuType:   req.AdminRouterMenuType,
				AdminRouterMenuName:   req.AdminRouterMenuName,
				AdminRouterIconType:   req.AdminRouterIconType,
				AdminRouterIcon:       req.AdminRouterIcon,
				AdminRouterRouteName:  req.AdminRouterRouteName,
				AdminRouterRoutePath:  req.AdminRouterRoutePath,
				AdminRouterComponent:  req.AdminRouterComponent,
				AdminRouterPathParam:  req.AdminRouterPathParam,
				AdminRouterStatus:     req.AdminRouterStatus,
				AdminRouterActiveMenu: req.AdminRouterActiveMenu,
				AdminRouterHideInMenu: req.AdminRouterHideInMenu,
				AdminRouterPid:        req.AdminRouterPid,
				AdminRouterSequence:   req.AdminRouterSequence,
				AdminRouterOrder:      req.AdminRouterOrder,
				AdminRouterI18nKey:    req.AdminRouterI18nKey,
				AdminRouterKeepAlive:  req.AdminRouterKeepAlive,
				AdminRouterConstant:   req.AdminRouterConstant,
				AdminRouterHref:       req.AdminRouterHref,
				AdminRouterMultiTab:   req.AdminRouterMultiTab,
				AdminRouterSystemType: req.AdminRouterSystemType,
			}
			err := adminRouterDAO.AdminRouterUpdate(request, tx)
			if err != nil {
				return errors.New(fmt.Sprintf("更新路由失败: %v", err.Error()))
			}

			// 更新角色
			return l.handleUpdateRole(req, tx, int(req.Id))
		}
		return nil
	})

	if err != nil {
		return xerr.ErrCodeMsg(xerr.ServerOperationExceptionError, err.Error())
	}
	return nil
}

func (l *AdminRouterEditLogic) handleUpdateRole(req *types.AdminRouterEditRequest, tx *ent.Tx, routerId int) error {
	adminRoleDAO := permission.NewAdminRoleDao(l.ctx, l.svcCtx)

	// 更新普通用户 和 超级管理员权限
	if req.AdminRouterSystemType == bizadmin.TypeBase {
		// 查询普通用户角色
		conditions := make([]predicate.AdminRole, 0, 2)
		conditions = append(conditions, adminrole.AdminRoleTypeEQ(bizadmin.TypeNormal))
		conditions = append(conditions, adminrole.IsDeleteEQ(bizadmin.NotDelete))
		adminRole, err := adminRoleDAO.AdminRoleFirst(conditions)
		if err != nil {
			return errors.New(fmt.Sprintf("查询普通用户角色失败: %v", err.Error()))
		}

		// 更新
		if !common.IsContain(adminRole.AdminRoleRouterIds, strconv.Itoa(routerId)) {
			if adminRole.AdminRoleRouterIds == "" {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%d", routerId)
			} else {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%s,%d", adminRole.AdminRoleRouterIds, routerId)
			}
			_ = adminRoleDAO.AdminRoleUpdate(adminRole, tx)
		}

		// 查询超级管理员角色
		conditions = make([]predicate.AdminRole, 0, 2)
		conditions = append(conditions, adminrole.AdminRoleTypeEQ(bizadmin.TypeSuper))
		conditions = append(conditions, adminrole.IsDeleteEQ(bizadmin.NotDelete))
		adminRole, err = adminRoleDAO.AdminRoleFirst(conditions)
		if err != nil {
			return errors.New(fmt.Sprintf("查询超级管理员角色失败: %v", err.Error()))
		}

		// 更新
		if !common.IsContain(adminRole.AdminRoleRouterIds, strconv.Itoa(routerId)) {
			if adminRole.AdminRoleRouterIds == "" {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%d", routerId)
			} else {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%s,%d", adminRole.AdminRoleRouterIds, routerId)
			}
			_ = adminRoleDAO.AdminRoleUpdate(adminRole, tx)
		}
	} else {
		// 查询普通用户角色
		conditions := make([]predicate.AdminRole, 0, 2)
		conditions = append(conditions, adminrole.AdminRoleTypeEQ(bizadmin.TypeNormal))
		conditions = append(conditions, adminrole.IsDeleteEQ(bizadmin.NotDelete))
		adminRole, err := adminRoleDAO.AdminRoleFirst(conditions)
		if err != nil {
			return errors.New(fmt.Sprintf("查询普通用户角色失败: %v", err.Error()))
		}
		// 更新
		if common.IsContain(adminRole.AdminRoleRouterIds, strconv.Itoa(routerId)) {
			adminRole.AdminRoleRouterIds = common.DeleteStr(adminRole.AdminRoleRouterIds, strconv.Itoa(routerId))
			_ = adminRoleDAO.AdminRoleUpdate(adminRole, tx)
		}

		// 查询超级管理员角色
		conditions = make([]predicate.AdminRole, 0, 2)
		conditions = append(conditions, adminrole.AdminRoleTypeEQ(bizadmin.TypeSuper))
		conditions = append(conditions, adminrole.IsDeleteEQ(bizadmin.NotDelete))
		adminRole, err = adminRoleDAO.AdminRoleFirst(conditions)
		if err != nil {
			return errors.New(fmt.Sprintf("查询超级管理员角色失败: %v", err.Error()))
		}

		// 更新
		if !common.IsContain(adminRole.AdminRoleRouterIds, strconv.Itoa(routerId)) {
			if adminRole.AdminRoleRouterIds == "" {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%d", routerId)
			} else {
				adminRole.AdminRoleRouterIds = fmt.Sprintf("%s,%d", adminRole.AdminRoleRouterIds, routerId)
			}
			_ = adminRoleDAO.AdminRoleUpdate(adminRole, tx)
		}
	}

	return nil
}
